package com.expert.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.expert.Mapper.CategoryMapper;
import com.expert.constant.MessageConstant;
import com.expert.context.BaseContext;
import com.expert.dto.EditCategoryDTO;
import com.expert.exception.AddException;
import com.expert.exception.DeleteException;
import com.expert.exception.UpdateException;
import com.expert.pojo.Category;
import com.expert.pojo.Expert;
import com.expert.pojo.User;
import com.expert.service.CategoryService;
import com.expert.service.ExpertService;
import com.expert.service.UserService;
import com.expert.vo.CategoryVo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @ClassName: CategoryServiceImpl
 * @Author: cxs
 * @Date: 2024/03/12 14:39
 * @Description:
 **/
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    UserService userService;

    @Autowired
    ExpertService expertService;

    /**
     * 分页查询专家分类信息
     *
     * @param page          当前页
     * @param pageSize      每页条数
     * @param categoryCode  分类代码
     * @param categoryName  分类名
     * @param categoryLevel 分类级别
     * @param categoryParent 父级分类
     * @return categoryVo 封装的分类信息
     */
    @Override
    public Page<CategoryVo> pageCategory(int page, int pageSize, String categoryCode, String categoryName, Integer categoryLevel,Long categoryParent) {

        Page<Category> categoryPage=new Page<>(page,pageSize);
        page(categoryPage,new LambdaQueryWrapper<Category>()
                .like(StringUtils.isNotEmpty(categoryCode),Category::getCategoryCode,categoryCode)
                .like(StringUtils.isNotEmpty(categoryName),Category::getCategoryName,categoryName)
                .eq(categoryLevel!=null,Category::getCategoryLevel,categoryLevel)
                .eq(categoryParent!=null,Category::getCategoryParent,categoryParent)
                .orderByAsc(Category::getCategoryCode)
        );
        List<Category> categoryList = categoryPage.getRecords();
        Page<CategoryVo> categoryVoPage=new Page<>();
        BeanUtils.copyProperties(categoryPage,categoryVoPage);
        //构建CategoryVo
        List<CategoryVo> categoryVoList = categoryList.stream().map(item -> {
            CategoryVo categoryVo = new CategoryVo();
            BeanUtils.copyProperties(item, categoryVo);
            Long itemCategoryParent = item.getCategoryParent();
            Category pageCategory = this.lambdaQuery().eq(Category::getId, itemCategoryParent).one();
            User user = this.userService.lambdaQuery().eq(User::getId, item.getCreateUser()).one();
            categoryVo.setCreateUserName(user.getName());
            if (pageCategory==null){
                categoryVo.setCategoryParentName("");
            }else {
                categoryVo.setCategoryParentName(pageCategory.getCategoryName());
            }
            return categoryVo;
        }).toList();
        categoryVoPage.setRecords(categoryVoList);
        return categoryVoPage;
    }

    /**
     * 根据分类级别查询对于的父级分类信息
     *
     * @param level 父级分类级别
     * @return 父级分类信息
     */
    @Override
    public List<Category> getCategoryParent(Integer level) {
        return this.lambdaQuery().eq(Category::getCategoryLevel, level-1).orderByAsc(Category::getCategoryCode).list();
    }

    /**
     * 添加分类信息
     *
     * @param category 前端传递的分类参数
     */
    @Override
    public void addCategory(Category category) {
        List<Category> categoryCodeList = this.lambdaQuery().eq(StringUtils.isNotEmpty(category.getCategoryCode()), Category::getCategoryCode, category.getCategoryCode()).list();
        if (categoryCodeList.size()!=0){
            throw new AddException(MessageConstant.CATEGORY_CODE_REPEAT);
        }
        Long categoryCount= this.lambdaQuery()
                .eq(StringUtils.isNotEmpty(category.getCategoryCode()),Category::getCategoryCode,category.getCategoryCode())
                .eq(StringUtils.isNotEmpty(category.getCategoryName()), Category::getCategoryName, category.getCategoryName()).count();
        if (categoryCount>0){
            throw new AddException(MessageConstant.CATEGORY_NAME_REPEAT);
        }
        if (category.getCategoryLevel()!=0&&category.getCategoryParent()==null){
            throw new AddException(MessageConstant.CATEGORY_PARENT_EMPTY);
        }
        if (category.getCategoryLevel()==0){
            category.setCategoryParent(0L);
        }
        category.setCreateUser(BaseContext.getCurrentId());
        category.setUpdateUser(BaseContext.getCurrentId());
        category.setCreateTime(LocalDateTime.now());
        category.setUpdateTime(LocalDateTime.now());
        this.save(category);
    }

    /**
     * 删除分类信息
     *
     * @param ids ids
     */
    @Override
    @Transactional
    public void deleteCategory(List<Long> ids) {
        //TODO 修改分类删除条件满足使用后不能删除
        ids.forEach(id->{
            Long count = this.lambdaQuery().eq(Category::getCategoryParent, id).count();
            if (count>0){
                throw  new DeleteException("该分类为其他分类的父级分类！");
            }
            Long expertCount=this.expertService.lambdaQuery().eq(Expert::getExpertCategory,id).count();
            if (expertCount>0){
                throw new DeleteException("该分类下存在专家信息，删除失败");
            }
        });
        this.removeBatchByIds(ids);
    }

    /**
     * 根据id查询分类信息
     *
     * @param id 分类id
     * @return category
     */
    @Override
    public Category selectById(Long id) {
        return this.lambdaQuery().eq(Category::getId,id).one();
    }

    /**
     * 修改分类信息
     *
     * @param editCategoryDTO 前端传递的分类信息
     */
    @Override
    public void updateCategory(EditCategoryDTO editCategoryDTO) {
        if (editCategoryDTO.getCategoryName()==null|| "".equals(editCategoryDTO.getCategoryName())){
            throw  new UpdateException(MessageConstant.CATEGORY_NAME_EMPTY);
        }
        if (editCategoryDTO.getCategoryCode()==null|| "".equals(editCategoryDTO.getCategoryCode())){
            throw  new UpdateException(MessageConstant.CATEGORY_CODE_EMPTY);
        }
        Long codeRepeatCount = this.lambdaQuery().ne(Category::getId,editCategoryDTO.getId()).eq(Category::getCategoryCode, editCategoryDTO.getCategoryCode()).count();
        if (codeRepeatCount>0){
            throw new UpdateException(MessageConstant.CATEGORY_CODE_REPEAT);
        }
        Category dbCategory = this.lambdaQuery().eq(Category::getId, editCategoryDTO.getId()).one();
        BeanUtils.copyProperties(editCategoryDTO,dbCategory);
        dbCategory.setUpdateTime(LocalDateTime.now());
        dbCategory.setUpdateUser(BaseContext.getCurrentId());
        this.updateById(dbCategory);
    }

    /**
     * 获取所以父级分类
     *
     * @return categoryList
     */
    @Override
    public List<Category> getCategoryAllParent() {
        List<Long> parentIdCondition=new ArrayList<>();
        Collections.addAll(parentIdCondition,0L,1L);
        return this.lambdaQuery().in(Category::getCategoryLevel, parentIdCondition).orderByAsc(Category::getCategoryCode).list();
    }

    @Override
    public List<Category> getCategoryByParentAndLevel(Long parent, Integer level) {
        return this.lambdaQuery()
                .eq(parent!=null,Category::getCategoryParent,parent)
                .eq(level!=null,Category::getCategoryLevel,level).list();
    }

    /**
     * 根据分类名查询分类
     *
     * @param name
     * @return
     */
    @Override
    public List<Category> selectByName(String name) {
        return this.lambdaQuery().like(Category::getCategoryName,name).list();
    }
}
